﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;

namespace iReaper.IndexBuilder.WWESource
{
    class LiveMeetingLandingUrlChecker
    {
        private int _iFlag;
        private AutoResetEvent _completEvent;
        private bool _isRunning;
        private int _iCount;
        private Semaphore semaphore;

        private void Init()
        {
            _iFlag = 0;
            _iCount = 0;
            _completEvent = new AutoResetEvent(false);
            _isRunning = true;
            semaphore = new Semaphore(10, 10);
        }

        public void Process(ChannelInfo[] infos)
        {
            if (null == infos)
            {
                throw new ArgumentNullException("infos");
            }

            if (_isRunning)
            {
                throw new ApplicationException("This crawler is in use.");
            }

            Init();

            int i = 0;

            foreach (ChannelInfo info in infos)
            {
                foreach (ChannelInfoItem channelItem in info.Items)
                {
                    foreach (EventItem item in channelItem.Events)
                    {
                        Uri destUri = new Uri(item.DownloadUrl);
                        if (destUri.Scheme != "http" && destUri.Scheme != "https")
                        {
                            continue;
                        }

                        Thread.Sleep(300);
                        semaphore.WaitOne();

                        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(item.DownloadUrl);
                        request.KeepAlive = true;
                        request.Pipelined = true;
                        request.Method = "HEAD";
                        request.AllowAutoRedirect = true;
                        Interlocked.Increment(ref _iFlag);
                        CheckObject obj = new CheckObject();
                        obj.Request=request;
                        obj.Item = item;
                        request.BeginGetResponse(new AsyncCallback(OnRequestBack), obj);

                        Interlocked.Increment(ref iIssued);
                        Console.Write(_iCount + "," + iIssued + "\r");
                    }
                }
            }
            if (i > 0)
            {
                _completEvent.WaitOne();
            }
        }

        int iIssued = 0;

        private void OnRequestBack(IAsyncResult ar)
        {
            HttpWebResponse response = null;
            try
            {
                CheckObject obj = (CheckObject)ar.AsyncState;
                response = (HttpWebResponse)obj.Request.EndGetResponse(ar);
                Uri uri = response.ResponseUri;
                obj.Item.DownloadUrl = uri.AbsoluteUri;

                Dictionary<string, string> queryDict = new Dictionary<string, string>();
                string query = uri.Query;
                if (query.Length == 0)
                {
                    return;
                }
                else
                {
                    query = query.Substring(1);
                }
                string[] states = query.Split('&');
                foreach (string state in states)
                {
                    string[] result = state.Split('=');
                    queryDict.Add(result[0], result[1]);
                }
                queryDict["cn"] = "anonymous";
                queryDict["company"] = "anonymous";
                queryDict["email"] = "anonymous@hotmail.com";
                StringWriter stringW = new StringWriter();
                foreach (KeyValuePair<string, string> pair in queryDict)
                {
                    stringW.Write(pair.Key);
                    stringW.Write('=');
                    stringW.Write(pair.Value);
                    stringW.Write('&');
                }
                StringBuilder sb = stringW.GetStringBuilder();
                sb.Length--;
                query = sb.ToString();

                if (uri.Host == "www106.livemeeting.com")
                {
                    string str3 = uri.AbsoluteUri.Replace(uri.Query, "");
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(str3 + ".wmv?fmt=dll");
                    request.Method = "POST";
                    request.AllowAutoRedirect = true;
                    request.Referer = str3;
                    StreamWriter writer2 = new StreamWriter(request.GetRequestStream());
                    writer2.Write(query);
                    writer2.Close();
                    request.ContentType = "application/x-www-form-urlencoded";
                    obj.Request = request;
                    request.BeginGetResponse(new AsyncCallback(this.OnCheckUrlBack), obj);
                }
            }
            catch (WebException exception)
            {
                if (exception.Response != null)
                {
                    response = (HttpWebResponse)exception.Response;
                }
            }
            catch { }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
                semaphore.Release();
                Interlocked.Increment(ref _iCount);
                int flag = Interlocked.Decrement(ref _iFlag);
                if (flag == 0)
                {
                    _completEvent.Set();
                    _isRunning = false;
                }
            }
        }

        private void OnCheckUrlBack(IAsyncResult ar)
        {
            CheckObject obj = (CheckObject)ar.AsyncState;
            HttpWebResponse response = (HttpWebResponse)obj.Request.EndGetResponse(ar);

            if (response.ContentType == "binary/octet-stream")
            {
                Uri responseUri = response.ResponseUri;
                string schema = responseUri.Scheme;
                string host = responseUri.Host;
                string absolutePath = responseUri.AbsolutePath;

                obj.Item.LiveMeetingUrl = schema + "://" + host + absolutePath;
            }

            response.Close();
        }

        class CheckObject
        {
            public HttpWebRequest Request
            {
                get;
                set;
            }

            public EventItem Item
            {
                get;
                set;
            }
        }

    }
}
